/**
 * 
 */
package io.gitee.falllee.dao.core.table;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import io.gitee.falllee.dao.cache.DataCache;
import io.gitee.falllee.dao.enums.EnableConfigEnum;
import io.gitee.falllee.dao.enums.SyncDatePrecisionEnum;
import io.gitee.falllee.dao.model.BaseDaoConfig;
import io.gitee.falllee.dao.model.DaoConst;
import io.gitee.falllee.dao.persistence.DataMapper;

/**
 * @author batty
 * @date 2022-06-27
 *
 */
public class TableBuilder {
    
    private DataMapper dataMapper;

    private DataCache dataCache;
    
    private BaseDaoConfig daoConfig;
    
    private String tableName;
    
    private String keyField = "id";
    
    /**
     * 是否启用缓存,0:默认(使用全局配置);1:启用缓存;2:禁用缓存
     * 
     * @return
     */
    private Integer cache = 0;

    /**
     * 是否启用Kafka消息,如果启用，在数据发生增、删、改后会发送消息,0:默认(使用全局配置);1:启用消息;2:禁用消息
     * 
     * @return
     */
    private Integer kafka = 0;
    
    /**
     * 原子缓存时间，默认一天
     */
    private Long expireTime = 86400L;
    
    /**
     * 列表缓存时间，默认半小时
     */
    private Long expireTimeList = 1800L;
    
    /**
     * 是否同步表（同步表的固定字段取实体传递的值）
     * 
     * @return
     */
    private boolean syncTable = false;

    /**
     * 同步时间字段（如果syncTable=true，则可以指定此字段为同步时间字段，取数据库当前时间）
     * 
     * @return
     */
    private String syncDateField = "";
    
    /**
     * 同步时间精度
     * 
     * @return
     */
    private SyncDatePrecisionEnum syncDatePrecision = SyncDatePrecisionEnum.SENCEND;
    
    public TableBuilder(DataMapper dataMapper, DataCache dataCache, BaseDaoConfig daoConfig, String tableName) {
        this.dataMapper = dataMapper;
        this.dataCache = dataCache;
        this.daoConfig = daoConfig;
        this.tableName = tableName;
    }
    
    String getTableName() {
        return this.tableName;
    }
    
    String getKeyField() {
        return this.keyField;
    }
    
    Integer getCache() {
        return this.cache;
    }
    
    Integer getKafka() {
        return this.kafka;
    }
    
    Long getExpireTime() {
        return this.expireTime;
    }
    
    Long getExpireTimeList() {
        return this.expireTimeList;
    }
    
    boolean syncTable() {
        return this.syncTable;
    }
    
    String syncDateField() {
        return this.syncDateField;
    }
    
    SyncDatePrecisionEnum syncDatePrecision() {
        return this.syncDatePrecision;
    }
    
    DataMapper getDataMapper() {
        return this.dataMapper;
    }
    
    DataCache getDataCache() {
        return this.dataCache;
    }
    
    BaseDaoConfig getDaoConfig() {
        return this.daoConfig;
    }
    
    public TableBuilder keyField(String keyField) {
        this.keyField = keyField;
        return this;
    }
    
    public TableBuilder cache(EnableConfigEnum cache) {
        this.cache = cache.getConfig();
        return this;
    }
    
    public TableBuilder kafka(EnableConfigEnum kafka) {
        this.kafka = kafka.getConfig();
        return this;
    }
    
    public TableBuilder expireTime(Long expireTime) {
        this.expireTime = expireTime;
        return this;
    }
    
    public TableBuilder expireTimeList(Long expireTimeList) {
        this.expireTimeList = expireTimeList;
        return this;
    }
    
    public SelectBuilder selectBuilder() {
        return new SelectBuilder(this);
    }
    
    public InsertBuilder insertBuilder() {
        return new InsertBuilder(this);
    }
    
    public UpdateBuilder updateBuilder() {
        return new UpdateBuilder(this);
    }
    
    public DeleteBuilder deleteBuilder() {
        return new DeleteBuilder(this);
    }
    
    public RestoreBuilder restoreBuilder() {
        return new RestoreBuilder(this);
    }
    
    public CacheBuilder cacheBuilder() {
        return new CacheBuilder(this);
    }
    
    public MessageBuilder messageBuilder() {
        return new MessageBuilder(this);
    }
    
    public ExtendBuilder extend() {
        return new ExtendBuilder(this);
    }

    /**
     * 从DB获取主键值
     * 
     * @param map
     * @param keyField
     * @param start
     * @param rows
     * @param end
     * @return
     */
    List<Object> getKeyList(Map<String, Object> map, String keyField, Long start, Long rows, Long end) {
        List<Object> keyList = new ArrayList<>();
        map.put(DaoConst.FIELD, keyField);
        map.put(DaoConst.START, start);
        map.put(DaoConst.ROWS, rows);
        map.put(DaoConst.END, end);
        List<Map<String, Object>> keyMapList = dataMapper.select(map);
        for (Map<String, Object> keyMap : keyMapList) {
            Object obj = keyMap.get(keyField);
            if (obj != null) {
                keyList.add(obj);
            }
        }
        return keyList;
    }
}
